#ifndef __GLF_CORE_ALIGNEDSTATICARRAY_H_INCLUDED__
#define __GLF_CORE_ALIGNEDSTATICARRAY_H_INCLUDED__

#include <glf/config.h>

namespace glf {

//! Aligned static array.
/**
 *  This helper class is required because this syntax:
 *
 *    __declspec(align(sizeof(U))) T p[S];
 *
 *  is not supported by Visual Studio. __descpsec(align(...)) absolutely wants a number, and
 *  doesn't work with sizeof(U). The trick here use partial template specialization to acheive a
 *  more flexible syntax.
 */
template<typename T, size_t S, size_t A>
struct AlignedStaticArray
{
	// GLF_STATIC_ASSERT is a function, so we'll do the static assert "manually".
	char error[A == 0 ? 1 : 0];
};

/** Declare partial template specialization of aligned_static_array with different alignment. */
#define PTS_ALIGNED_STATIC_ARRY_DECLARATION(A) \
	template<typename T, size_t S> \
	struct AlignedStaticArray<T, S, A> \
	{ \
		GLF_ATTRIBUTE_ALIGN(A) T p[S]; \
	}

// Declare all possible alignment from 1 to 256.
PTS_ALIGNED_STATIC_ARRY_DECLARATION(1);
PTS_ALIGNED_STATIC_ARRY_DECLARATION(2);
PTS_ALIGNED_STATIC_ARRY_DECLARATION(4);
PTS_ALIGNED_STATIC_ARRY_DECLARATION(8);
PTS_ALIGNED_STATIC_ARRY_DECLARATION(16);
PTS_ALIGNED_STATIC_ARRY_DECLARATION(32);
PTS_ALIGNED_STATIC_ARRY_DECLARATION(64);
PTS_ALIGNED_STATIC_ARRY_DECLARATION(128);
PTS_ALIGNED_STATIC_ARRY_DECLARATION(256);

} // end namespace glf

#endif // __GLF_CORE_ALIGNEDSTATICARRAY_H_INCLUDED__

